package pe.gob.proviasnac.app.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;

import com.google.gson.Gson;

import pe.gob.proviasnac.app.dto.Detallemercancia;
import pe.gob.proviasnac.app.dto.Detallevehiculo;
import pe.gob.proviasnac.app.dto.Documentoexpediente;
import pe.gob.proviasnac.app.dto.Expedienteautorizacion;
import pe.gob.proviasnac.app.dto.Historialexpediente;
import pe.gob.proviasnac.app.dto.Repositorioarchivo;
import pe.gob.proviasnac.app.model.ModelHelper;
import pe.gob.proviasnac.app.mybatis.SessionFactory;
import pe.gob.proviasnac.app.utiles.Constantes;
import pe.gob.proviasnac.app.utiles.DataTable;
import pe.gob.proviasnac.app.utiles.ResultTransacction;
import pe.gob.proviasnac.app.utiles.SecuenciaUtil;
import pe.gob.proviasnac.app.utiles.SessionUtil;
import pe.gob.proviasnac.app.utiles.FichaVehiculo;

public class GenerarExpedienteAutorizacionAction extends ModelHelper {

	private static final long serialVersionUID = 4043342532544302457L;
	
	private Expedienteautorizacion expediente;
	private Detallevehiculo vehiculo;
	private Detallemercancia mercancia;
	private File solicitud;
	private String solicitudContentType;
	private String solicitudFileName;
	private String ruta;
	private Integer indexItem;
	private String stringJson;
	private String criterioVehiculo;
	private Integer indexMercancia;
	private Long pesoTotal;
	private Integer indexFichaVehicular;
	
	Gson json = new Gson();
	ResultTransacction transact = new ResultTransacction();
	
	private ResultTransacction resultTransacction = new ResultTransacction();
	
	public String generarExpediente() throws Exception{
		

		List<FichaVehiculo> fichasVehiculos = (ArrayList<FichaVehiculo>) SessionUtil.getSesion().getAttribute(Constantes.SESION_FICHA_VEHICULOS);
		
		if(fichasVehiculos == null || fichasVehiculos.isEmpty()){
			resultTransacction.setCodeResult(Constantes.BUSINESS_EXCEPTION);
			resultTransacction.setMessage(Constantes.MSG_03);
		}else{
			session = SessionFactory.getSqlSessionFactory().openSession();
			
			if(expediente.getApoyoPolicial().intValue() == 0){
				expediente.setCantidadUnidades(0);
			}
			
			List<String> rutas =  (ArrayList<String>) SessionUtil.getSesion().getAttribute(Constantes.SESION_RUTAS);
			if(rutas != null){
				expediente.setRutas(json.toJson(rutas));
			}
			
			Integer secuenciaExpediente = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_EXPEDIENTE,session);
			expediente.setIdExpedienteAutorizacion(secuenciaExpediente);
			expediente.setEstado(Constantes.ESTADO_ACTIVO);
			this.insertar(expediente);
			
			
			for(FichaVehiculo x : fichasVehiculos){
				
				Integer secuenciaRemolque = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_DETALLEVEHICULO,session);
				x.getRemolcador().setIdExpedienteAutorizacion(secuenciaExpediente);
				x.getRemolcador().setIdDetalleVehiculo(secuenciaRemolque);
				this.insertar(x.getRemolcador());
				
				Integer secuenciaTrailer = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_DETALLEVEHICULO,session);
				x.getTrailer().setIdExpedienteAutorizacion(secuenciaExpediente);
				x.getTrailer().setIdDetalleVehiculo(secuenciaTrailer);
				x.getTrailer().setIdDetalleVehiculoRecursivo(secuenciaRemolque);
				this.insertar(x.getTrailer());
				
				
				for(Detallemercancia m : x.getMercancias()){
					Integer secuenciaMercancia = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_DETALLEMERCANCIA,session);
					m.setIdDetalleMercancia(secuenciaMercancia);
					m.setIdDetalleVehiculo(secuenciaRemolque);
					this.insertar(m);
				}
			}
			
			Integer secuenciaRepositorio = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_REPOSITORIOARCHIVO,session);
			InputStream is = new FileInputStream(solicitud);
			Repositorioarchivo repo = new Repositorioarchivo();
			repo.setFile(IOUtils.toByteArray(is));
			repo.setName(this.solicitudFileName);
			repo.setType(this.solicitudContentType);
			repo.setIdFile(secuenciaRepositorio);
			this.insertar(repo);
			
			Integer secuenciaDocumentoExpediente = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_DOCUMENTOEXPEDIENTE,session);
			Documentoexpediente doc = new Documentoexpediente();
			doc.setIdDocumentoExpediente(secuenciaDocumentoExpediente);
			doc.setIdExpedienteAutorizacion(secuenciaExpediente);
			doc.setIdFile(secuenciaRepositorio);
			doc.setTipoDocumento(Constantes.TIPO_DOCUMENTO_SOLICITUD);
			this.insertar(doc);
			
			Integer secuenciaHistorial = SecuenciaUtil.obtenerSecuencia(Constantes.TABLA_HISTORIAL,session);
			Historialexpediente historial = new Historialexpediente();
			historial.setEstado(Constantes.ESTADO_ACTIVO);
			historial.setIdExpediente(secuenciaExpediente);
			historial.setIdHistorialExpediente(secuenciaHistorial);
			this.insertar(historial);
			
			this.commit();
			this.close();
			resultTransacction.setMessage("Transaccion exitosa, Expediente de Autorizacion Especial Generado.");
		}

		return SUCCESS;
		
	}
	
	public String eliminarFichaVehicular(){
		List<FichaVehiculo> fichasVehiculos = (ArrayList<FichaVehiculo>) SessionUtil.getSesion().getAttribute(Constantes.SESION_FICHA_VEHICULOS);
		if(fichasVehiculos != null){
			
			for(int i=0;i<fichasVehiculos.size();i++){
				if(fichasVehiculos.get(i).getRemolcador().getIdDetalleVehiculo().intValue() == indexFichaVehicular.intValue()){
					fichasVehiculos.remove(i);
				}
			}
			
			
			SessionUtil.getSesion().setAttribute(Constantes.SESION_FICHA_VEHICULOS, fichasVehiculos);
		}
		stringJson = json.toJson(transact);
		return SUCCESS;
	}
	
	public String cancelarFichaVehicular(){
		SessionUtil.getSesion().removeAttribute(Constantes.SESION_VEHICULO);
		stringJson = json.toJson(transact);
		return SUCCESS;
	}
	
	public String editarFichaVehicular(){
		
		List<FichaVehiculo> fichasVehiculos = (ArrayList<FichaVehiculo>) SessionUtil.getSesion().getAttribute(Constantes.SESION_FICHA_VEHICULOS);
		for(int i=0;i<fichasVehiculos.size();i++){
			System.out.println("Id Remolcadores: " + fichasVehiculos.get(i).getRemolcador().getIdDetalleVehiculo());
			if(fichasVehiculos.get(i).getRemolcador().getIdDetalleVehiculo().intValue() == indexFichaVehicular.intValue()){
				System.out.println("id Encontrado");
				FichaVehiculo sesionVehiculo = fichasVehiculos.get(i);
				System.out.println(sesionVehiculo.toString());
				SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);
			}
		}

		stringJson = json.toJson(transact);
		return SUCCESS;
	}
	
	public String obtenerTotalPeso(){
		
		FichaVehiculo sesionVehiculo = (FichaVehiculo) SessionUtil.getSesion().getAttribute(Constantes.SESION_VEHICULO);
		Long pesoTotal = new Long(0);
		if(sesionVehiculo != null){
			pesoTotal = sesionVehiculo.getRemolcador().getPesoTara();
			pesoTotal = pesoTotal + sesionVehiculo.getTrailer().getPesoTara();
			System.out.println("Cantidad Mercancias: "+ sesionVehiculo.getMercancias().size());
			for(Detallemercancia x : sesionVehiculo.getMercancias()){
				pesoTotal = pesoTotal + x.getPeso();
				System.out.println(x.getPeso());
			}
		}

		this.pesoTotal = pesoTotal;
		return SUCCESS;
	}
	
	public String agregarFichaVehicular(){
		
		FichaVehiculo sesionVehiculo = (FichaVehiculo) SessionUtil.getSesion().getAttribute(Constantes.SESION_VEHICULO);
		if(sesionVehiculo != null){
		if(sesionVehiculo.getRemolcador() != null && sesionVehiculo.getTrailer() != null && !sesionVehiculo.getMercancias().isEmpty()){
			
			List<FichaVehiculo> fichasVehiculos = (ArrayList<FichaVehiculo>) SessionUtil.getSesion().getAttribute(Constantes.SESION_FICHA_VEHICULOS);
			
			if(fichasVehiculos == null){
				fichasVehiculos = new ArrayList<FichaVehiculo>();
			}
			
			if(sesionVehiculo.getRemolcador().getIdDetalleVehiculo() == null){
				
				if(fichasVehiculos.isEmpty()){
					sesionVehiculo.getRemolcador().setIdDetalleVehiculo(new Integer(1));
					fichasVehiculos.add(sesionVehiculo);
				}else{
					
					sesionVehiculo.getRemolcador().setIdDetalleVehiculo(fichasVehiculos.get(fichasVehiculos.size()-1).getRemolcador().getIdDetalleVehiculo()+1);
					fichasVehiculos.add(sesionVehiculo);
					
				}
			}else{

				for(int i=0;i<fichasVehiculos.size();i++){
					if(fichasVehiculos.get(i).getRemolcador().getIdDetalleVehiculo().intValue() == sesionVehiculo.getRemolcador().getIdDetalleVehiculo().intValue()){
						fichasVehiculos.set(i, sesionVehiculo);
					}
				}
				
			}
			
			SessionUtil.getSesion().removeAttribute(Constantes.SESION_VEHICULO);
			SessionUtil.getSesion().setAttribute(Constantes.SESION_FICHA_VEHICULOS, fichasVehiculos);
			
		}else{
			transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
			transact.setMessage(Constantes.MSG_01);
		}

		
		}else{
			transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
			transact.setMessage(Constantes.MSG_01);
		}
		
		stringJson = json.toJson(transact);
		
		return SUCCESS;
		
	}
	
	public String eliminarMercancia(){
		
		FichaVehiculo sesionVehiculo = (FichaVehiculo) SessionUtil.getSesion().getAttribute(Constantes.SESION_VEHICULO);
		if(sesionVehiculo != null){
			sesionVehiculo.getMercancias().remove(this.indexMercancia.intValue());
			SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);
		}
		
		return SUCCESS;
	}
	
	public String agregarMercancia(){
		
		FichaVehiculo sesionVehiculo = (FichaVehiculo) SessionUtil.getSesion().getAttribute(Constantes.SESION_VEHICULO);
		if(sesionVehiculo == null){
			sesionVehiculo = new FichaVehiculo();
		}
		
		if(sesionVehiculo.getMercancias().size()<4){
			if(sesionVehiculo.getRemolcador() != null && sesionVehiculo.getTrailer() != null){
				
				Long pesoTotal = new Long(0);
				pesoTotal = sesionVehiculo.getRemolcador().getPesoTara();
				pesoTotal = pesoTotal + sesionVehiculo.getTrailer().getPesoTara();
				pesoTotal = pesoTotal + mercancia.getPeso();
				for(Detallemercancia x : sesionVehiculo.getMercancias()){
					pesoTotal = pesoTotal + x.getPeso();
				}
				
				if(pesoTotal <= 48000){
					
					//if(mercancia.getAlto() < sesionVehiculo.getTrailer().getAlto()){
						
						
						//if(mercancia.getAncho() < sesionVehiculo.getTrailer().getAncho()){
							sesionVehiculo.getMercancias().add(mercancia);
							SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);
						//}else{
							//transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
							//transact.setMessage(Constantes.RN_12);
						//}
						

					//}else{
						//transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
						//transact.setMessage(Constantes.RN_11);
					//}
					

				}else{
					transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
					transact.setMessage(Constantes.RN_10);
				}

			}else{

				transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
				transact.setMessage(Constantes.MSG_02);
			
			}

		}else{
			transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
			transact.setMessage(Constantes.RN_09);
		}
		stringJson = json.toJson(transact);
		return SUCCESS;
	}
	
	public String eliminarVehiculo(){
		
		FichaVehiculo sesionVehiculo = (FichaVehiculo) SessionUtil.getSesion().getAttribute(Constantes.SESION_VEHICULO);
		if(sesionVehiculo != null){
			if(this.criterioVehiculo.equals(Constantes.TIPO_UNIDAD_REMOLCADOR)){
				sesionVehiculo.setRemolcador(null);
				SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);
			}else if(this.criterioVehiculo.equals(Constantes.TIPO_UNIDAD_CAMA_BAJA) || this.criterioVehiculo.equals(Constantes.TIPO_UNIDAD_SEMI_TRAILER)){
				sesionVehiculo.setTrailer(null);
				SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);		
			}
		}

		return SUCCESS;
	}
	
	public String agregarVehiculo(){
		
		FichaVehiculo sesionVehiculo = (FichaVehiculo) SessionUtil.getSesion().getAttribute(Constantes.SESION_VEHICULO);
		
		if(sesionVehiculo == null){
			sesionVehiculo = new FichaVehiculo();
		}
		
		if(this.vehiculo.getTipoUnidad().equals(Constantes.TIPO_UNIDAD_REMOLCADOR)){
			if(sesionVehiculo.getRemolcador() == null){
				sesionVehiculo.setRemolcador(vehiculo);
				SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);
			}else{
				transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
				transact.setMessage(Constantes.RN_07);
			}
		}else if(this.vehiculo.getTipoUnidad().equals(Constantes.TIPO_UNIDAD_CAMA_BAJA) || this.vehiculo.getTipoUnidad().equals(Constantes.TIPO_UNIDAD_SEMI_TRAILER)){
			if(sesionVehiculo.getTrailer() == null){
				sesionVehiculo.setTrailer(vehiculo);
				SessionUtil.getSesion().setAttribute(Constantes.SESION_VEHICULO, sesionVehiculo);
			}else{
				transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
				transact.setMessage(Constantes.RN_08);
			}
		}
		stringJson = json.toJson(transact);
		
		return SUCCESS;
	}
	
	public String getVehiculos(){
		
		DataTable dt = new DataTable();
		
		List<FichaVehiculo> fichasVehiculos = (ArrayList<FichaVehiculo>) SessionUtil.getSesion().getAttribute(Constantes.SESION_FICHA_VEHICULOS);
		
		if(fichasVehiculos != null){
			for(FichaVehiculo x:fichasVehiculos){
				dt.getAaData().add(x.getRemolcador());
			}
		}
		
		Gson json = new Gson();
		stringJson = json.toJson(dt);
		
		System.out.println(dt.toString());
		
		return SUCCESS;
	}
	
	public String agregarRuta(){

		transact.setCodeResult(Constantes.TRANSACT_SUCCESS);
		
		List<String> rutas =  (ArrayList<String>) SessionUtil.getSesion().getAttribute(Constantes.SESION_RUTAS);
		if(rutas == null){
			rutas = new ArrayList<String>();
		}
		if(!rutas.contains(this.ruta)){
			if(rutas.size() < 4){
				rutas.add(this.ruta);
				SessionUtil.getSesion().setAttribute(Constantes.SESION_RUTAS, rutas);
			}else{
				transact.setCodeResult(Constantes.BUSINESS_EXCEPTION);
				transact.setMessage(Constantes.RN_06);
			}
		}
		stringJson = json.toJson(transact);
		return SUCCESS;
	}
	
	public String eliminarRuta(){
		List<String> rutas =  (ArrayList<String>) SessionUtil.getSesion().getAttribute(Constantes.SESION_RUTAS);
		if(rutas != null){
					rutas.remove(this.indexItem.intValue());
					if(rutas.isEmpty()){
						SessionUtil.getSesion().removeAttribute(Constantes.SESION_RUTAS);
					}
		}
		return SUCCESS;
	}
		
	public Expedienteautorizacion getExpediente() {
		return expediente;
	}
	public void setExpediente(Expedienteautorizacion expediente) {
		this.expediente = expediente;
	}
	public Detallevehiculo getVehiculo() {
		return vehiculo;
	}
	public void setVehiculo(Detallevehiculo vehiculo) {
		this.vehiculo = vehiculo;
	}
	public Detallemercancia getMercancia() {
		return mercancia;
	}
	public void setMercancia(Detallemercancia mercancia) {
		this.mercancia = mercancia;
	}
	public File getSolicitud() {
		return solicitud;
	}
	public void setSolicitud(File solicitud) {
		this.solicitud = solicitud;
	}
	public String getSolicitudContentType() {
		return solicitudContentType;
	}
	public void setSolicitudContentType(String solicitudContentType) {
		this.solicitudContentType = solicitudContentType;
	}
	public String getSolicitudFileName() {
		return solicitudFileName;
	}
	public void setSolicitudFileName(String solicitudFileName) {
		this.solicitudFileName = solicitudFileName;
	}
	public String getRuta() {
		return ruta;
	}
	public void setRuta(String ruta) {
		this.ruta = ruta;
	}

	public Integer getIndexItem() {
		return indexItem;
	}

	public void setIndexItem(Integer indexItem) {
		this.indexItem = indexItem;
	}

	public String getStringJson() {
		return stringJson;
	}

	public void setStringJson(String stringJson) {
		this.stringJson = stringJson;
	}

	public String getCriterioVehiculo() {
		return criterioVehiculo;
	}

	public void setCriterioVehiculo(String criterioVehiculo) {
		this.criterioVehiculo = criterioVehiculo;
	}

	public Integer getIndexMercancia() {
		return indexMercancia;
	}

	public void setIndexMercancia(Integer indexMercancia) {
		this.indexMercancia = indexMercancia;
	}

	public Long getPesoTotal() {
		return pesoTotal;
	}

	public void setPesoTotal(Long pesoTotal) {
		this.pesoTotal = pesoTotal;
	}

	public Integer getIndexFichaVehicular() {
		return indexFichaVehicular;
	}

	public void setIndexFichaVehicular(Integer indexFichaVehicular) {
		this.indexFichaVehicular = indexFichaVehicular;
	}

	public ResultTransacction getResultTransacction() {
		return resultTransacction;
	}

	public void setResultTransacction(ResultTransacction resultTransacction) {
		this.resultTransacction = resultTransacction;
	}

}
